var __slice = [].slice;

define(["_", "./dom", "./utils"], function(_, dom, utils) {
  var addAttributes, addAttributesAndBody, buildTree, createElement;
  createElement = function(elementDescription) {
    var element, elementName, terms;
    terms = utils.trim(elementDescription).split(".");
    elementName = terms.shift() || "div";
    element = document.createElement(elementName);
    if (terms.length) {
      element.className = terms.join(" ");
    }
    return element;
  };
  addAttributes = function(element, attributes) {
    var eventName, handler, name, value, wrapper;
    if (!attributes) {
      return;
    }
    wrapper = dom(element);
    for (name in attributes) {
      value = attributes[name];
      if (name === "on") {
        for (eventName in value) {
          handler = value[eventName];
          wrapper.on(eventName, handler);
        }
      } else if (utils.startsWith(name, "on")) {
        wrapper.on(name.substring(2), value);
      } else {
        wrapper.attribute(name, value);
      }
    }
    return null;
  };
  addAttributesAndBody = function(element, body) {
    var elementDescription, nested, nestedBody, nestedElement, _i, _len;
    for (_i = 0, _len = body.length; _i < _len; _i++) {
      nested = body[_i];
      if (nested == null) {

      } else if (_.isString(nested)) {
        element.innerHTML += nested;
      } else if (_.isArray(nested)) {
        elementDescription = nested[0], nestedBody = 2 <= nested.length ? __slice.call(nested, 1) : [];
        nestedElement = buildTree(elementDescription, nestedBody);
        element.appendChild(nestedElement);
      } else if (_.isObject(nested)) {
        addAttributes(element, nested);
      } else {
        throw new Error("Unexpected body value <" + nested + "> while building DOM elements.");
      }
    }
    return null;
  };
  buildTree = function(elementDescription, body) {
    var currentDescription, element, nestedDescription, nestedElement, splitx;
    splitx = elementDescription.indexOf(">");
    currentDescription = splitx === -1 ? elementDescription : elementDescription.substring(0, splitx);
    element = createElement(currentDescription);
    if (splitx === -1) {
      addAttributesAndBody(element, body);
    } else {
      nestedDescription = elementDescription.substring(splitx + 1);
      nestedElement = buildTree(nestedDescription, body);
      element.appendChild(nestedElement);
    }
    return element;
  };
  return function() {
    var body, element, elementDescription;
    elementDescription = arguments[0], body = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
    element = buildTree(elementDescription, body);
    return dom(element);
  };
});
